﻿/************************************************************************

 This file is part of "10 Second Tim".

 "10 Second Tim" is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 "10 Second Tim" is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with "10 Second Tim".  If not, see <http://www.gnu.org/licenses/>.

************************************************************************/

// All code (c)2013 Scott Bevin. all rights reserved

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LDE;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace LudumDare27.Games.Game_1
{
	public class Tile
	{
		private Sprite m_sprite = null;
		public Vector2 Pos;

		public float GroundHeight;

		public Tile( Texture2D tex, Vector2 pos )
		{
			if ( tex != null )
				m_sprite = new Sprite( tex, 1 );

			Pos = pos;
		}

		public void Render( SpriteBatch sprites )
		{
			if ( m_sprite != null )
				m_sprite.Render( sprites, Pos );
		}

		public virtual bool IsCharSafe( Character c )
		{
			return true;
		}

		public virtual float GetGroundHeight( )
		{
			return GroundHeight;
		}
	}

	public class NormalTile : Tile
	{
		public NormalTile( ContentManager content, Vector2 pos )
			: base( content.Load<Texture2D>( "Img/G1/Tile1" ), pos )
		{
		}
	}

	public class StartPit : Tile
	{
		public StartPit( ContentManager content, Vector2 pos )
			: base( content.Load<Texture2D>( "Img/G1/Tile2" ), pos )
		{
		}
	}

	public class Pit : Tile
	{
		public Pit( ContentManager content, Vector2 pos )
			: base( null, pos )
		{
			GroundHeight = 1000.0f;
		}

		public override bool IsCharSafe( Character c )
		{
			return ( c.Jumping && c.Position.Y < 0.0f ) ||
				Math.Abs( Pos.X - c.Position.X ) > ( Defs.Game1.TileWidth * 0.4f );
		}
	}

	public class EndPit : Tile
	{
		public EndPit( ContentManager content, Vector2 pos )
			: base( content.Load<Texture2D>( "Img/G1/Tile3" ), pos )
		{
		}
	}

	public class OverheadBlock : Tile
	{
		public OverheadBlock( ContentManager content, Vector2 pos )
			: base( content.Load<Texture2D>( "Img/G1/Tile4" ), pos )
		{
		}

		public override bool IsCharSafe( Character c )
		{
			return ( c.Sliding );
		}
	}

	public class Terrain
	{
		public List<Tile> m_tiles = new List<Tile>( );

		private float TileWidth;

		public Terrain( GameScreen screen, int numtiles, float TileWidth, bool makeSafe )
		{
			this.TileWidth = TileWidth;
			Random rnd = new Random( );

			// Create 10 seconds worth of terrain (taking a guess)
			Vector2 pos = new Vector2( 0.0f, 0.0f );
			for ( int i = 0; i < numtiles; ++i )
			{
				int rndi = rnd.Next( 100 );

				if ( rndi < 50 || i < 5 || makeSafe )
				{
					m_tiles.Add( new NormalTile( screen.ContentManager, pos ) );
					pos.X += TileWidth;
				}
				else if ( rndi < 75 )
				{
					m_tiles.Add( new StartPit( screen.ContentManager, pos ) ); pos.X += TileWidth;
					m_tiles.Add( new Pit( screen.ContentManager, pos ) ); pos.X += TileWidth;
					m_tiles.Add( new EndPit( screen.ContentManager, pos ) ); pos.X += TileWidth;
					m_tiles.Add( new NormalTile( screen.ContentManager, pos ) ); pos.X += TileWidth;
				}
				else
				{
					m_tiles.Add( new OverheadBlock( screen.ContentManager, pos ) );
					pos.X += Defs.Game1.TileWidth;
					m_tiles.Add( new NormalTile( screen.ContentManager, pos ) );
					pos.X += Defs.Game1.TileWidth;

					if ( rnd.Next( 100 ) < 75 )
					{
						m_tiles.Add( new NormalTile( screen.ContentManager, pos ) );
						pos.X += Defs.Game1.TileWidth;
					}
				}
			}
		}

		public void Render( SpriteBatch sprites, Character c )
		{
			//GetTileAtPos( c.Position.X ).Render( sprites );

			foreach ( Tile t in m_tiles )
				t.Render( sprites );
		}

		public float GetGroundHeight( Character c )
		{
			return GetTileAtPos( c.Position.X ).GetGroundHeight( );
		}

		public bool CharSafe( Character c )
		{
			return GetTileAtPos( c.Position.X ).IsCharSafe( c );
		}

		public Tile GetTileAtPos( float x )
		{
			float xPos = x;
			int tile = (int)( ( xPos + ( TileWidth * 0.5f ) ) / TileWidth );

			if ( tile < 0 )
				tile = 0;

			if ( tile >= m_tiles.Count )
				tile = m_tiles.Count - 1;

			return m_tiles[ tile ];
		}
	}
}